#include "searchlist.h"
#include "tcpmanager.h"
#include "adduseritem.h"
#include "findsuccessdlg.h"
#include "loadingdlg.h"
#include "findfaildlg.h"
#include "customizeedit.h"
#include "usermanager.h"

#include <QEvent>
#include <QWheelEvent>
#include <QScrollBar>
#include <QDebug>
#include <QJsonDocument>


SearchList::SearchList(QWidget *parent)
    : QListWidget(parent), m_find_dlg(nullptr), m_search_edit(nullptr), m_send_pending(false)
{
    Q_UNUSED(parent);
    // 默认关闭滚动条
    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    // 安装事件过滤器
    this->viewport()->installEventFilter(this);
    // 连接点击的信号和槽
    connect(this, &QListWidget::itemClicked, this, &SearchList::slot_item_clicked);

    //添加条目
    addTipItem();
    // 连接搜索条目
    connect(TcpManager::getInstance().get(), &TcpManager::sig_user_search, this, &SearchList::slot_user_search);
}

// 清除弹出的添加好友框
void SearchList::clearFindDlg()
{
    if (m_find_dlg) {
        m_find_dlg->hide();
        m_find_dlg = nullptr;
    }
}

void SearchList::setSearchEdit(QWidget *edit)
{
    m_search_edit = edit;
}

void SearchList::closeFindDlg()
{
    if (m_find_dlg) {
        m_find_dlg->hide();
        m_find_dlg = nullptr;
    }
}

bool SearchList::eventFilter(QObject *object, QEvent *event)
{
    // 检测是否鼠标悬浮进入或者离开
    if (object == this->viewport()) {
        if (event->type() == QEvent::Enter) {
            // 鼠标悬浮，显示滚动条
            this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        } else if (event->type() == QEvent::Leave) {
            // 鼠标离开，隐藏滚动条
            this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        }
    }

    // 检测事件是否是鼠标滚轮事件
    if (object == this->viewport() && event->type() == QEvent::Wheel) {
        QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
        int numDegrees = wheelEvent->angleDelta().y() / 8;
        int numSteps = numDegrees / 15; // 计算滚动步数

        // 设置滚动幅度
        this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() - numSteps);

        // 停止事件传递
        return true;
    }

    return QListWidget::eventFilter(object, event);
}

void SearchList::addTipItem()
{
    auto* invalid_item = new QWidget();
    QListWidgetItem* item_tmp = new QListWidgetItem;
    item_tmp->setSizeHint(QSize(250, 10));
    this->addItem(item_tmp);
    invalid_item->setObjectName("invalid_item");
    this->setItemWidget(item_tmp, invalid_item);
    item_tmp->setFlags(item_tmp->flags() & ~Qt::ItemIsSelectable);

    auto* add_user_item = new AddUserItem();
    QListWidgetItem* item = new QListWidgetItem;
    item->setSizeHint(add_user_item->sizeHint());
    this->addItem(item);
    this->setItemWidget(item, add_user_item);
}

// 等待发送查找联系人之后的后端处理
void SearchList::waitPending(bool pending)
{
    if (pending) {
        m_loadingDialog = new LoadingDlg(this);
        m_loadingDialog->setModal(true);
        m_loadingDialog->show();
        m_send_pending = pending;
    } else {
        m_loadingDialog->hide();
        m_loadingDialog->deleteLater();
        m_send_pending = pending;
    }
}

// 处理联系人条目被点击的信号
void SearchList::slot_item_clicked(QListWidgetItem* item)
{
    // 获取自定义的widget对象
    QWidget* widget = this->itemWidget(item);
    if (!widget) {
        qDebug() << "slot item clicked widget is nullptr......";
        return ;
    }

    // 对获取的widget进行操作，并将其转换为ListItemBase
    ListItemBase* customItem = qobject_cast<ListItemBase*>(widget);
    if (!customItem) {
        qDebug() << "slot item clicked widget is nullptr......";
        return ;
    }

    auto itemType = customItem->getListItemType();
    if (itemType == ListItemType::INVALID_ITEM) {
        qDebug() << "slot invalid item clicked......";
        return ;
    }

    if (itemType == ListItemType::ADD_USER_TIP_ITEM) {
        // 后台正在处理中
        if (m_send_pending) {
            return ;
        }

        if (!m_search_edit) {
            return ;
        }

        waitPending(true);
        auto search_edidt = dynamic_cast<CustomizeEdit*>(m_search_edit);
        if (search_edidt == nullptr) {
            qDebug() << "dynamic_cast<CustomizeEdit*>(m_search_edit) failed......";
            return ;
        }
        auto uid_str = search_edidt->text();

        // 发送添加好友请求给服务器server
        QJsonObject jsonObj;
        jsonObj["uid"] = uid_str;
        QJsonDocument doc(jsonObj);
        QByteArray jsonData = doc.toJson(QJsonDocument::Compact);

        // 发送tcp请求给Chaterver
        emit TcpManager::getInstance()->sig_send_data(ReqId::ID_SEARCH_USER_REQ, jsonData);

        return ;
    }

    // 清除弹出的添加好友框
    clearFindDlg();
}

void SearchList::slot_user_search(std::shared_ptr<SearchInfo> search_info)
{
    waitPending(false);
    // 搜索失败
    if (search_info == nullptr) {
        m_find_dlg = std::make_shared<FindFailDlg>(this);
    } else {
        // 如果搜索到四自己，则暂且返回
        auto self_uid = UserManager::getInstance()->getUid();
        if (search_info->m_uid == self_uid) {
            return ;
        }
        /*
         * 添加好友的两种情况:
         *                      1. 搜索到的好友已近是好友了
         *                      2. 未添加的好友
         *
         */
        bool b_exist = UserManager::getInstance()->checkFriendById(search_info->m_uid);
        if (b_exist) {
            // 处理已经添加的好友，进行页面跳转
            emit sig_jump_chat_item(search_info);
            return ;
        }
        // 处理未添加的好友
        m_find_dlg = std::make_shared<FindSuccessDlg>(this);
        auto sptr = std::dynamic_pointer_cast<FindSuccessDlg>(m_find_dlg);
        if (sptr == nullptr) {
            qDebug() << "std::dynamic_pointer_cast<FindSuccessDlg>(m_find_dlg) failed ......";
            return ;
        }
        sptr->setSearchInfo(search_info);
    }

    m_find_dlg->show();
}

